/*
 * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "sle_connect_hdi.h"
#include "sle_connect_config.h"
#include "sle_hal_errcode.h"
#include "sle_hilog.h"
#include "sle_connection_manager.h"
#include "sle_callback_adapter.h"

SleHdiErrorCode SleHdiAdapterConnectRemote(const SleDeviceAddress *addr)
{
    SLE_ASSERT_AND_RETURN_RET(addr != NULL, SLE_HDI_ERRCODE_INVALID_PARAM);
    SleHdiErrorCode ret = SLE_HDI_ERRCODE_FAIL;
    sle_addr_t addr_sdk = {
        .type = (uint8_t)addr->addrType,
    };
    memcpy(&addr_sdk.addr, addr->addr, sizeof(addr_sdk.addr));
    ret = sle_connect_remote_device(&addr_sdk);
    return ret;
}

SleHdiErrorCode SleHdiAdapterDisconnectRemote(const SleDeviceAddress *addr)
{
    SLE_ASSERT_AND_RETURN_RET(addr != NULL, SLE_HDI_ERRCODE_INVALID_PARAM);
    SleHdiErrorCode ret = SLE_HDI_ERRCODE_FAIL;
    sle_addr_t addr_sdk = {
        .type = (uint8_t)addr->addrType,
    };
    memcpy(&addr_sdk.addr, addr->addr, sizeof(addr_sdk.addr));
    ret = sle_disconnect_remote_device(&addr_sdk);
    return ret;
}

SleHdiErrorCode SleHdiAdapterUpdateConnectParam(const SleConnectionParamUpdate *params)
{
    SLE_ASSERT_AND_RETURN_RET(params != NULL, SLE_HDI_ERRCODE_INVALID_PARAM);
    sle_connection_param_update_t params_sdk;
    memcpy(&params_sdk, params, sizeof(sle_connection_param_update_t));
    SleHdiErrorCode ret = SLE_HDI_ERRCODE_FAIL;
    ret = sle_update_connect_param(&params_sdk);
    return ret;
}

SleHdiErrorCode SleHdiAdapterPairRemote(const SleDeviceAddress *addr)
{
    SLE_ASSERT_AND_RETURN_RET(addr != NULL, SLE_HDI_ERRCODE_INVALID_PARAM);
    SleHdiErrorCode ret = SLE_HDI_ERRCODE_FAIL;
    sle_addr_t addr_sdk = {
        .type = (uint8_t)addr->addrType,
    };
    memcpy(&addr_sdk.addr, addr->addr, sizeof(addr_sdk.addr));
    ret = sle_pair_remote_device(&addr_sdk);
    return ret;
}

SleHdiErrorCode SleHdiAdapterRemovePairedDevice(const SleDeviceAddress *addr)
{
    SLE_ASSERT_AND_RETURN_RET(addr != NULL, SLE_HDI_ERRCODE_INVALID_PARAM);
    SleHdiErrorCode ret = SLE_HDI_ERRCODE_FAIL;
    sle_addr_t addr_sdk = {
        .type = (uint8_t)addr->addrType,
    };
    memcpy(&addr_sdk.addr, addr->addr, sizeof(addr_sdk.addr));
    ret = sle_remove_paired_remote_device(&addr_sdk);
    return ret;
}

SleHdiErrorCode SleHdiAdapterRemoveAllPairs(void)
{
    SleHdiErrorCode ret = SLE_HDI_ERRCODE_FAIL;
    ret = sle_remove_all_pairs();
    return ret;
}

SleHdiErrorCode SleHdiAdapterGetPairedDevicesNum(uint16_t *number)
{
    SLE_ASSERT_AND_RETURN_RET(number != NULL, SLE_HDI_ERRCODE_INVALID_PARAM);
    SleHdiErrorCode ret = SLE_HDI_ERRCODE_FAIL;
    ret = sle_get_paired_devices_num(number);
    return ret;
}

SleHdiErrorCode SleHdiAdapterGetPairedDevices(SleDeviceAddress *addr, uint16_t *number)
{
    SLE_ASSERT_AND_RETURN_RET(addr != NULL, SLE_HDI_ERRCODE_INVALID_PARAM);
    SLE_ASSERT_AND_RETURN_RET(number != NULL, SLE_HDI_ERRCODE_INVALID_PARAM);
    SleHdiErrorCode ret = SLE_HDI_ERRCODE_FAIL;
    sle_addr_t addr_sdk = {
        .type = (uint8_t)addr->addrType,
    };
    memcpy(&addr_sdk.addr, addr->addr, sizeof(addr_sdk.addr));
    ret = sle_get_paired_devices(&addr_sdk, number);
    return ret;
}

SleHdiErrorCode SleHdiAdapterGetPairState(const SleDeviceAddress *addr, SlePairState *state)
{
    SLE_ASSERT_AND_RETURN_RET(addr != NULL, SLE_HDI_ERRCODE_INVALID_PARAM);
    SLE_ASSERT_AND_RETURN_RET(state != NULL, SLE_HDI_ERRCODE_INVALID_PARAM);
    SleHdiErrorCode ret = SLE_HDI_ERRCODE_FAIL;
    sle_addr_t addr_sdk = {
        .type = (uint8_t)addr->addrType,
    };
    uint8_t state_sdk; 
    memcpy(&addr_sdk.addr, addr->addr, sizeof(addr_sdk.addr));
    ret = sle_get_pair_state(&addr_sdk, &state_sdk);
    *state = (SlePairState)state_sdk;
    return ret;
}

SleHdiErrorCode SleHdiAdapterReadRemoteDeviceRssi(uint16_t connectId)
{
    SleHdiErrorCode ret = SLE_HDI_ERRCODE_FAIL;
    ret = sle_read_remote_device_rssi(connectId);
    return ret;
}

SleHdiErrorCode SleHdiAdapterSetDataLen(uint16_t connectId, uint16_t dataMaxLen)
{
    SleHdiErrorCode ret = SLE_HDI_ERRCODE_FAIL;
    ret = sle_set_data_len(connectId, dataMaxLen);
    return ret;
}

SleHdiErrorCode SleHdiAdapterSetPhyParam(uint16_t connectId, const SleConnectionPhyParam *phyParam)
{
    SLE_ASSERT_AND_RETURN_RET(phyParam != NULL, SLE_HDI_ERRCODE_INVALID_PARAM);
    sle_set_phy_t params_sdk;
    memcpy(&params_sdk, phyParam, sizeof(sle_set_phy_t));
    SleHdiErrorCode ret = SLE_HDI_ERRCODE_FAIL;
    ret = sle_set_phy_param(connectId, &params_sdk);
    return ret;
}

SleHdiErrorCode SleHdiAdapterSetMcsValue(uint16_t connectId, uint8_t mcs)
{
    SleHdiErrorCode ret = SLE_HDI_ERRCODE_FAIL;
    ret = sle_set_mcs(connectId, mcs);
    return ret;
}

SleHdiErrorCode SleHdiAdapterRegisterConnectCallbacks(SleConnectHdiCallbacks *callback)
{
    SLE_ASSERT_AND_RETURN_RET(callback != NULL, SLE_HDI_ERRCODE_INVALID_PARAM);
    SleHdiErrorCode ret = SLE_HDI_ERRCODE_FAIL;
    ret = RegisterConnectCallbackAdapter(callback);
    return ret;
}

SleHdiErrorCode GetSleConnectHdiOpts(SleConnectHdiOpts *connectOpts)
{
    SLE_ASSERT_AND_RETURN_RET(connectOpts != NULL, SLE_HDI_ERRCODE_FAIL);
    connectOpts->connectRemote = SleHdiAdapterConnectRemote;
    connectOpts->disconnectRemote = SleHdiAdapterDisconnectRemote;
    connectOpts->updateConnectParam = SleHdiAdapterUpdateConnectParam;
    connectOpts->sendPairReq = SleHdiAdapterPairRemote;
    connectOpts->removePairDevice = SleHdiAdapterRemovePairedDevice;
    connectOpts->removeAllPairs = SleHdiAdapterRemoveAllPairs;
    connectOpts->getPairedDevicesNum = SleHdiAdapterGetPairedDevicesNum;
    connectOpts->getPairedDevices = SleHdiAdapterGetPairedDevices;
    connectOpts->getPairState = SleHdiAdapterGetPairState;
    connectOpts->readRemoteRssi = SleHdiAdapterReadRemoteDeviceRssi;
    connectOpts->setDataLen= SleHdiAdapterSetDataLen;
    connectOpts->setPhyParam = SleHdiAdapterSetPhyParam;
    connectOpts->setMcsValue = SleHdiAdapterSetMcsValue;
    connectOpts->registerConnectCbks = SleHdiAdapterRegisterConnectCallbacks;
    return SLE_HDI_ERRCODE_SUCC;
}